package com.gopay.bis.service.bank.impl;

import java.util.Date;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.gopay.bis.dao.bankorder.BankContractSerialInfoDAO;
import com.gopay.bis.manager.bank.tolly.BisQueryValidatorManager;
import com.gopay.bis.manager.bank.tolly.BisRealNameCertifyManager;
import com.gopay.bis.service.bank.BankAuthOrderService;
import com.gopay.common.Result;
import com.gopay.common.cipher.utils.LoggerMaskUtils;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.BankContractConstants;
import com.gopay.common.constants.bank.BankOrderType;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.bank.BisBankInterfaceChannel;
import com.gopay.common.constants.bank.CmbcConstants;
import com.gopay.common.constants.bank.outside.TollyConstants;
import com.gopay.common.constants.cust.CustPersonInfoConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.constants.trans.CertChannelCode;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.cps.manager.order.CpsGeneralMainOrderQueryManager;
import com.gopay.common.domain.bank.ExPayBaseMessage;
import com.gopay.common.domain.bank.cmbc.expay.CmbcExPayMessage;
import com.gopay.common.domain.bank.foundation.IdentityInfoMessage;
import com.gopay.common.domain.bank.outside.gboss.resp.query.validator.EduInfo;
import com.gopay.common.domain.bis.BisBankContractSerialInfo;
import com.gopay.common.domain.bis.BisRealNameCertify;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.CertNoVerifyUtil;
import com.gopay.common.util.spring.SpringContextUtil;
import com.gopay.remote.bank.BisCertificationRemoteService;
import com.gopay.remote.bank.ExPayInteractRemoteService;
import com.gopay.remote.bank.foundation.BankCardCertifyRemoteService;
import com.gopay.remote.bank.foundation.FourElementsCertifyRemoteService;
import com.gopay.remote.bank.foundation.MobileCertifyRemoteService;
import com.gopay.remote.bank.foundation.RealNameCertifyRemoteService;
import com.gopay.remote.bank.queryvalidator.QueryValidatorRemoteService;

/**
 * 银行卡鉴权实现
 * 
 * @BisCertificationServiceImpl.java
 * @author zhengxue @2015-9-28 下午2:27:25 www.gopay.com.cn Inc.All rights
 *         reserved.
 */
@Service("bisCertificationService")
public class BisCertificationServiceImpl implements BisCertificationRemoteService {

    private static Logger logger = LoggerFactory.getLogger(BisCertificationServiceImpl.class);
    @Resource(name = "realNameCertifyConfig")
    private Map<String, String> realNameCertifyConfig;

    @Resource(name = "bankAuthOrderService")
    private BankAuthOrderService bankAuthOrderService;

    @Resource(name = "cpsGeneralMainOrderQueryManager")
    private CpsGeneralMainOrderQueryManager mainOrderQuery;

    @Resource(name = "bisConfig")
    private Map<String, String> bisConfig;

    @Autowired
    private BisRealNameCertifyManager bisRealNameCertifyManager;
    @Autowired
    private BisQueryValidatorManager bisQueryValidatorManager;

    @Resource(name = "bankContractSerialInfoDAO")
    private BankContractSerialInfoDAO bankContractSerialInfoDAO;

    public static final String TBANK_C = "123456"; // 国付宝自己定义的测试银行信用卡
    public static final String TBANK_D = "223456"; // 国付宝自己定义的测试银行借用卡

    @Override
    public Result cardCertification(ExPayBaseMessage base) {
        // 日志输出隐藏信用卡cvv2
        ExPayBaseMessage logData = getPrintMsg(base);
        /**央行检测 要求身份照掩码处理 sj 2017-11-02*/
        logger.error(
                "BisCertificationServiceImpl.cardCertification request：" + logData.toString());
        Result result = new Result();
        try {
        	if(!CertChannelCode.HUAFU2.value.equals(base.getSpecial2())){
        		checkRequest(base);
        	}
            
            if ("TBANK".equals(base.getBank())
                    && (base.getCardNo().startsWith(TBANK_D) || base.getCardNo().startsWith(TBANK_C))) {
                // 根据环境返回TBANK结果，生产返回失败其他环境返回成功
                if ("on".equals(bisConfig.get("BIS.TBANK.FLAG"))) {
                    // TBANK返回成功
                    result.setModel("flag", true);
                } else {
                    // TBANK返回失败
                    result.setModel("flag", false);
                }
                result.setSuccess(true);
                return result;
            }
            /*boolean authOrderMark = false; // 为true插入认证订单
            String outStlmCd = BankConstants.BANK_LOGO_CMBCADPAY; // 默认走民生通道
            base.setOutStlmCd(outStlmCd);
            base.setBankIntrChann(BisBankInterfaceChannel._11);
            // 因有些产品线调用时没有传该字段，会导致民生代扣插入时报空指针
            if (null == base.getBankBusProd()) {
                base.setBankBusProd(BisBankBusinessProd._19);
            }
            base.setBankOrderType(BankOrderType.GOPAY_BIS_ORDER);// 订单类型：新平台订单
            // 获取SPRING加载的快捷BeanName
            String beanName = outStlmCd + "-" + "EXPAY";
            ExPayInteractRemoteService exPayService = (ExPayInteractRemoteService) SpringContextUtil.getBean(beanName);
            // 只有委托代收鉴权交易才插入认证订单表
            if (StringUtils.isNotBlank(base.getOrderId())) {
                // 获取主订单表
                CpsGenMainOrder mainOrder = mainOrderQuery.get(base.getOrderId());
                if ((null != mainOrder) && (IntTxnCd._00664.value.equals(mainOrder.getGopayIntTxnCd()))) {
                    bankAuthOrderService.addBankAuthOrder(base);
                    authOrderMark = true;
                }
            }
            if(authOrderMark){//只有委托代收的鉴权必须是走民生代扣的通道
            	result = exPayService.certification(base);
                
                // 只有委托代收鉴权交易才插入认证订单表
//                if (authOrderMark) {
                    if (!result.isSuccess()) {
                        // 更新认证主订单为认证失败
                        bankAuthOrderService.updateBackVerifyFail(base);
                    } else if ((boolean) result.getModel("flag")) {
                        // 更新认证主订单为认证通过
                        bankAuthOrderService.updateBackSuccess(base);
                    } else {
                        // 更新认证主订单为认证不通过
                        bankAuthOrderService.updateBackFail(base);
                    }
//                }
            } else {//其他的鉴权都是可以切换通道的
        		outStlmCd = bisConfig.get("BIS.BANK.CARD.CERTIFY.TYPE");
        		if (BisBankBusinessProd._19.equals(base.getBankBusProd())) {
        			outStlmCd = "CMBCADPAY";
        		}
        		beanName = outStlmCd + "-" + "CERTIFY";
        		BankCardCertifyRemoteService bankCardCertifyService = (BankCardCertifyRemoteService) SpringContextUtil.getBean(beanName);
        		result = bankCardCertifyService.bankCardCertify(base);
            }*/
            
            String outStlmCd = bisConfig.get("BIS.BANK.CARD.CERTIFY.TYPE");
            base.setBankIntrChann(BisBankInterfaceChannel._14);
            base.setBankBusProd(BisBankBusinessProd._19);
            base.setOutStlmCd(outStlmCd);
            base.setBankOrderType(BankOrderType.GOPAY_BIS_ORDER);// 订单类型：新平台订单
    		String beanName = outStlmCd + "-" + "CERTIFY";
    		BankCardCertifyRemoteService bankCardCertifyService = (BankCardCertifyRemoteService) SpringContextUtil.getBean(beanName);
    		result = bankCardCertifyService.bankCardCertify(base);
            
            logger.error(
                    "BisCertificationServiceImpl.cardCertification res：" + result.toString());
        } catch (GopayException e) {
            logger.error("BisCertificationServiceImpl.cardCertification error: ", e);
            result.setResultCode(e.getErrCode());
            result.setSuccess(false);
        } catch (Exception e) {
            logger.error("BisCertificationServiceImpl.cardCertification: ", e);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100F1002);
            result.setSuccess(false);
        }
        return result;
    }

    /**
     * 基础参数检查
     * 
     * @param request
     * @throws GopayException
     */
    private void checkRequest(ExPayBaseMessage request) throws GopayException {
        String phoneNo = request.getMediaId();
        String cardHolder = request.getCardHolder();
        String cardNo = request.getCardNo();
        String bank = request.getBank();
        String cidNo = request.getIdentityCode();

        if (StringUtils.isBlank(phoneNo)) {
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E6073);
        }
        if (StringUtils.isBlank(cardHolder)) {
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E6072);
        }
        if (StringUtils.isBlank(cardNo)) {
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E6069);
        }
        if (StringUtils.isBlank(bank)) {
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E1135);
        }
        if (StringUtils.isBlank(cidNo)) {
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E6075);
        }
        if (!CertNoVerifyUtil.verify(cidNo)) {
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E6075);
        }
    }

    /**
     * 快捷对象输出，隐藏信用卡cvv2
     * 
     * @param baseMsg
     * @return
     */
    private ExPayBaseMessage getPrintMsg(ExPayBaseMessage baseMsg) {
        ExPayBaseMessage logData = new ExPayBaseMessage();
        BeanUtils.copyProperties(baseMsg, logData);
        if (logData.getCvv2() == null || "".equals(logData.getCvv2())) {
            //
        } else {
            logData.setCvv2("***");
        }
        return logData;
    }

    @Override
    public Result realNameCertify(IdentityInfoMessage base) {
    	/**央行检测 要求身份照掩码处理 ssj 2017-05-05*/
        logger.error("BisCertificationServiceImpl.realNameCertify request:"+LoggerMaskUtils.maskString(ToStringBuilder.reflectionToString(base)));
        /**
         * flag表示业务认证成功或者失败，success表示当前操作是否成功
         */
        Result result = new Result();
        /**
         * 如果认证开关关闭直接返回结果
         */
        if ("off".equals(bisConfig.get("BIS.AUTH.SWITCH"))) {
            logger.info("--该环境认证开关已关闭--");
            result.setSuccess(true);
            result.setModel("flag", true);
            result.setResultCode(ProcCodeConstants.PROC_CODE_200W1001);
            result.setErrorMsg("该环境认证开关已关闭");
            return result;
        }
        /*
         * 验证输入参数是否正确
         */
        if (!checkRealNameRequest(base, result)) {
            return result;
        }

        //标记是否是客户端通过调用国政通来进行实名
        boolean isGZTCertifi = false ;
        String channelCode = null;

        try {
            String outStlmcd = null;
            // 根据调用方传的渠道调用标示，判断认证渠道
            if (null != base.getChannelMak()) {
                if (CertChannelCode.GZT.value.equals(base.getChannelMak())) {
                    outStlmcd = "gBoss";
                }
                if (CertChannelCode.ZCXZX.value.equals(base.getChannelMak())) {
                    outStlmcd = "zcxzx";
                }
                if (CertChannelCode.ZCXY.value.equals(base.getChannelMak())) {
                    outStlmcd = "zcxy";
                }
                if (CertChannelCode.HUAFU2.value.equals(base.getChannelMak())
                		|| CertChannelCode.HUAFU4.value.equals(base.getChannelMak())) {
                    outStlmcd = "hfdatas";
                }
            } else {
                // 如果没有传认证标示，默认走国政通
                outStlmcd = realNameCertifyConfig.get("REAL.NAME.CERTIFY.OUTSTLMCD");
            }

            //add by songfengli 20180312 由于国政通不在合作，所以不在使用国政通进行实名认证，
            // 国政通只用于账户等级升级，实名则使用中诚信为主，中诚信源为备的方案
            logger.info(LoggerMaskUtils.maskString(base.getCardHolder()) + "," +
                    LoggerMaskUtils.maskString(base.getIdentityCode()) +
                    ",客户认证的传入通道为："+outStlmcd +
                    ",base.isIdentity():"+base.isIdentity());
            if("gBoss".equals(outStlmcd) && base.isIdentity()){
                logger.info("调用国政通通道实名认证，需要转化为中诚信！！！");
                outStlmcd = "zcxzx";
                isGZTCertifi = true;
                channelCode = CertChannelCode.ZCXZX.value;
            }

            String beanName = outStlmcd + "ProviderClient";
            /*
             * 是否走直连验证实名认证,true每次都调用实名认证接口
             */
            if (!base.isDirectFlag()) {
                logger.info(
                		LoggerMaskUtils.maskString(base.getCardHolder()) + "," + 
                		LoggerMaskUtils.maskString(base.getIdentityCode()) + ",走有缓存接口调用认证！");
                /*
                 * 判断输入参数是否已经认证过，如果已经认证过，直接从数据库中获取历史信息返回，否则调用认证接口
                 */
                BisRealNameCertify bisRealNameCertify = bisRealNameCertifyManager
                        .getBisRealNameCertify(base.getCardHolder(), base.getIdentityCode(), outStlmcd);

                if ((null == bisRealNameCertify) || ((null != bisRealNameCertify)
                        && TollyConstants.REALNAME_STATUS_NOMONEY.equals(bisRealNameCertify.getState()))) {
                    // 调用实名认证接口
                    RealNameCertifyRemoteService realNameCertifyService = (RealNameCertifyRemoteService) SpringContextUtil
                            .getBean(beanName);
                    result = realNameCertifyService.realNameCertify(base);

                    logger.error("BisCertificationServiceImpl.realNameCertify res："
                            + result.toString());

                    if (null != result.getModel("status")) {
                        /*
                         * 增加结果到数据库中
                         */
                        insertBisRealNameCertify(base, result, outStlmcd);
                    }
                } else {
                    // 根据数据库记录状态返回调用者
                    if (bisRealNameCertify.getState().equals(TollyConstants.REALNAME_STATUS_CONSISTENT)) {
                        result.setSuccess(true);
                        result.setModel("flag", true);
                        logger.info("直接返回数据库记录，实名认证成功！");
                    } else if ((TollyConstants.REALNAME_STATUS_INCONSISTENT).equals(bisRealNameCertify.getState())) {
                        result.setSuccess(true);
                        result.setModel("flag", false);
                        logger.info("直接返回数据库记录，实名认证失败！");
                    } else {
                        result.setSuccess(false);
                        result.setModel("flag", false);
                        logger.info("直接返回数据库记录，实名认证不存在！");
                    }
                }
            } else {
            	/**央行检测 要求身份照掩码处理 ssj 2017-05-05*/
                logger.info(base.getCardHolder() + "," + LoggerMaskUtils.maskString(base.getIdentityCode()) + ",没有走缓存直接调用" + outStlmcd + "验证接口！");
                BisRealNameCertify bisRealNameCertify = bisRealNameCertifyManager
                        .getBisRealNameCertify(base.getCardHolder(), base.getIdentityCode(), outStlmcd);
                // 调用实名认证接口
                RealNameCertifyRemoteService realNameCertifyService = (RealNameCertifyRemoteService) SpringContextUtil
                        .getBean(beanName);
                result = realNameCertifyService.realNameCertify(base);

                logger.error("BisCertificationServiceImpl.realNameCertify res："
                        + result.toString());
                /*
                 * 认证成功，并且数据库中无此记录，保存数据到数据库中
                 */
                if (null == bisRealNameCertify) {

                    if (null != result.getModel("status")) {
                        /*
                         * 增加结果到数据库中
                         */
                        insertBisRealNameCertify(base, result, outStlmcd);
                    }
                }
            }
            logger.error("BisCertificationServiceImpl.realNameCertify response:"
                    + result.toString());
        } catch (Exception e) {
            logger.error("BisCertificationServiceImpl.realNameCertify: ", e);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100F1002);
            result.setSuccess(false);
            result.setModel("flag", false);
        }

        //add by songfengli 20180312 实名从国政通换成中诚信的通道，调用中诚信没有调用成功（是否调用成功；验证结果为成功），
        // 如果这两者结果都没成功，则还需要在通过中诚信源认证一遍
        if(isGZTCertifi && !(boolean)result.getModel("flag")){
            channelCode = CertChannelCode.ZCXY.value;
            result = gztIntoZcxy(base,result);
        }

        //将实名认证的渠道放入Map中返回，以便个人实名认证转化国政通
        result.setModel("channelCode", channelCode == null ? "" : channelCode);

        return result;
    }


    private Result gztIntoZcxy(IdentityInfoMessage base,Result result){
        logger.info("调用中诚信实名认证失败，需要转化为中诚信源再次实名认证！！！");
        String outStlmcd = "zcxy";
        String beanName = outStlmcd + "ProviderClient";
        logger.info("gztIntoZcxy()方法调用的beanName：{}",beanName);
        logger.info(LoggerMaskUtils.maskString(base.getCardHolder()) + "," +
                        LoggerMaskUtils.maskString(base.getIdentityCode()) + ",gztIntoZcxy()调用实名认证！");
         /* 判断输入参数是否已经认证过，如果已经认证过，直接从数据库中获取历史信息返回，否则调用认证接口*/
        BisRealNameCertify bisRealNameCertify = bisRealNameCertifyManager.getBisRealNameCertify(base.getCardHolder(), base.getIdentityCode(), outStlmcd);
        if (null == bisRealNameCertify) {
            //调用中诚信源实名认证接口
            try{
                RealNameCertifyRemoteService realNameCertifyService = (RealNameCertifyRemoteService) SpringContextUtil.getBean(beanName);
                result = realNameCertifyService.realNameCertify(base);
                logger.error("BisCertificationServiceImpl.realNameCertify res：" + result.toString());
                if (null != result.getModel("status")) {
                    insertBisRealNameCertify(base, result, outStlmcd);
                }
            }catch (Exception e){
                logger.error("gztIntoZcxy()实名异常:",e);
                result.setResultCode(ProcCodeConstants.PROC_CODE_100F1002);
                result.setSuccess(false);
                result.setModel("flag", false);
            }
        }else{
            // 根据数据库记录状态返回调用者
            if (bisRealNameCertify.getState().equals(TollyConstants.REALNAME_STATUS_CONSISTENT)) {
                logger.info("直接返回数据库记录，实名认证成功！");
                result.setSuccess(true);
                result.setModel("flag", true);
            } else if ((TollyConstants.REALNAME_STATUS_INCONSISTENT).equals(bisRealNameCertify.getState())) {
                logger.info("直接返回数据库记录，实名认证失败！");
                result.setSuccess(true);
                result.setModel("flag", false);
            } else {
                logger.info("直接返回数据库记录，实名认证不存在！");
                result.setSuccess(false);
                result.setModel("flag", false);
            }
        }

        return result;
    }

    /**
     * 
     * 功能描述：验证输入参数是否为空
     *
     * @param base
     * @param result
     * @return
     * 
     * @author 宣广海
     *
     * @since 2016年6月13日
     *
     * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
     */
    private boolean checkRealNameRequest(IdentityInfoMessage base, Result result) {
        if (StringUtils.isBlank(base.getCardHolder())) {
            result.setSuccess(false);
            result.setModel("flag", false);
            result.setResultCode(ProcCodeConstants.PROC_CODE_200E1001);
            result.setErrorMsg("请求参数-姓名（cardHolder）为空！");
            return false;
        }
        if (StringUtils.isBlank(base.getIdentityCode())) {
            result.setSuccess(false);
            result.setModel("flag", false);
            result.setResultCode(ProcCodeConstants.PROC_CODE_200E1001);
            result.setErrorMsg("请求参数-证件号码（identityCode）为空！");
            return false;
        }
        if (!CertNoVerifyUtil.verify(base.getIdentityCode())) {
            result.setSuccess(false);
            result.setModel("flag", false);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E6075);
            result.setErrorMsg("请求参数-证件号码格式错误");
            return false;
        }
        return true;
    }

    /**
     * 检查手机认证参数是否有效
     * 
     * @param base
     * @param result
     * @return
     * @author w_jiqing
     */
    private boolean checkMobileCertRequest(IdentityInfoMessage base, Result result) {
        if (StringUtils.isBlank(base.getCardHolder())) {
            result.setSuccess(false);
            result.setModel("flag", false);
            result.setResultCode(ProcCodeConstants.PROC_CODE_200E1001);
            result.setErrorMsg("请求参数-姓名（cardHolder）为空！");
            return false;
        }
        if (StringUtils.isBlank(base.getIdentityCode())) {
            result.setSuccess(false);
            result.setModel("flag", false);
            result.setResultCode(ProcCodeConstants.PROC_CODE_200E1001);
            result.setErrorMsg("请求参数-证件号码（identityCode）为空！");
            return false;
        }
        if (!CertNoVerifyUtil.verify(base.getIdentityCode())) {
            result.setSuccess(false);
            result.setModel("flag", false);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E6075);
            result.setErrorMsg("请求参数-证件号码格式错误");
            return false;
        }
        if (StringUtils.isBlank(base.getMobileNumber())) {
            result.setSuccess(false);
            result.setModel("flag", false);
            result.setResultCode(ProcCodeConstants.PROC_CODE_200E1001);
            result.setErrorMsg("请求参数-手机号码（mobileNumber）为空！");
            return false;
        }
        return true;
    }

    /**
     * 检查四要素参数是否为空
     * 
     * @param base
     * @param result
     * @return
     * @author w_jiqing
     */
    private boolean checkFourElementsCertRequest(IdentityInfoMessage base, Result result) {
        if (StringUtils.isBlank(base.getCardHolder())) {
            result.setSuccess(false);
            result.setModel("flag", false);
            result.setResultCode(ProcCodeConstants.PROC_CODE_200E1001);
            result.setErrorMsg("请求参数-姓名（cardHolder）为空！");
            return false;
        }
        if (StringUtils.isBlank(base.getIdentityCode())) {
            result.setSuccess(false);
            result.setModel("flag", false);
            result.setResultCode(ProcCodeConstants.PROC_CODE_200E1001);
            result.setErrorMsg("请求参数-证件号码（identityCode）为空！");
            return false;
        }
        if (!CertNoVerifyUtil.verify(base.getIdentityCode())) {
            result.setSuccess(false);
            result.setModel("flag", false);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E6075);
            result.setErrorMsg("请求参数-证件号码格式错误");
            return false;
        }
        if (StringUtils.isBlank(base.getMobileNumber())) {
            result.setSuccess(false);
            result.setModel("flag", false);
            result.setResultCode(ProcCodeConstants.PROC_CODE_200E1001);
            result.setErrorMsg("请求参数-手机号码（mobileNumber）为空！");
            return false;
        }
        if (StringUtils.isBlank(base.getBankCardNo())) {
            result.setSuccess(false);
            result.setModel("flag", false);
            result.setResultCode(ProcCodeConstants.PROC_CODE_200E1001);
            result.setErrorMsg("请求参数-银行卡号（bankCardNo）为空！");
            return false;
        }
        return true;
    }

    /**
     * 
     * 功能描述：增加数据到数据库中
     *
     * @param base
     * @param result
     * @param outStlmcd
     * 
     * @author 宣广海
     *
     * @since 2016年6月13日
     *
     * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
     */
    private void insertBisRealNameCertify(IdentityInfoMessage base, Result result, String outStlmcd) {
        try {
            BisRealNameCertify bisRealNameCertify = new BisRealNameCertify();
            bisRealNameCertify.setCardNo(base.getIdentityCode());
            bisRealNameCertify.setCardType(
                    base.getIdentityType() == null ? CustPersonInfoConstants.CERT_TYPE_IDCARD : base.getIdentityType());// 默认类型为身份证
            bisRealNameCertify.setCertifyCode(outStlmcd);
            bisRealNameCertify.setCertifyDate(new Date());
            bisRealNameCertify.setName(base.getCardHolder());
            bisRealNameCertify.setState((String) result.getModel("status"));
            bisRealNameCertify.setQuerySeq((String) result.getModel("querySeq"));
            if (null != base.getMobileNumber()) {
                bisRealNameCertify.setMobile(base.getMobileNumber());
            }
            if (null != base.getBankCardNo()) {
                bisRealNameCertify.setBankCardNo(base.getBankCardNo());
            }

            bisRealNameCertifyManager.insertBisRealNameCertify(bisRealNameCertify);
        } catch (Exception e) {
            logger.error("insertBisRealNameCertify is error!", e);
        }
    }

    /**
     * 
     * 功能描述：学历认证接口
     *
     * @param base
     * @author lilili
     *
     * @since 2016年6月13日
     * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
     */
    @Override
    public Result queryValidator(IdentityInfoMessage base) {
        /**
         * flag表示业务认证成功或者失败，success表示当前操作是否成功
         */
        Result result = new Result(false);
        /**
         * 如果认证开关关闭直接返回结果
         */
        if ("off".equals(bisConfig.get("BIS.AUTH.SWITCH"))) {
            logger.info("--该环境认证开关已关闭--");
            result.setSuccess(true);
            result.setModel("flag", true);
            result.setResultCode(ProcCodeConstants.PROC_CODE_200W1001);
            result.setErrorMsg("该环境认证开关已关闭");
            return result;
        }
        /*
         * 验证输入参数是否正确
         */
        if (!checkRealNameRequest(base, result)) {
            return result;
        }
        /**央行检测 要求身份照掩码处理 ssj 2017-05-05*/
        logger.error("queryValidator.entrance request：" + LoggerMaskUtils.maskString(ToStringBuilder.reflectionToString(base)));
        String beanName = "gBossEduProviderClient";
        QueryValidatorRemoteService queryValidatorService = (QueryValidatorRemoteService) SpringContextUtil
                .getBean(beanName);

        /*
         * 判断输入参数是否已经认证过，如果已经认证过，直接从数据库中获取历史信息返回，否则调用认证接口
         */
        EduInfo eduInfo = bisQueryValidatorManager.getEduInfo(base.getCardHolder(), base.getIdentityCode());
        if (null == eduInfo) {
            result = queryValidatorService.queryValidator(base);
            logger.error(
                    "BisCertificationServiceImpl.queryValidator res：" + ToStringBuilder.reflectionToString(result));
            if (null != result.getModel("status")) {
                /*
                 * 增加结果到数据库中
                 */
                insertBisQueryValidator(base, result);
            }
        } else {
            // 根据数据库记录状态返回调用者
            if (eduInfo.getStatus().equals("0")) {
                result.setSuccess(true);
                result.setModel("flag", true);
                logger.info("直接返回数据库记录，学历认证成功！");
            } else {
                result.setSuccess(true);
                result.setModel("flag", false);
                logger.info("直接返回数据库记录，学历认证失败！");
            }
        }

        return result;
    }

    /**
     * 手机号认证 （支持三大运营商）
     */
    @Override
    public Result mobileCertify(IdentityInfoMessage base) {
    	/**央行检测 要求身份照掩码处理 sj 2017-11-02*/
        logger.error("BisCertificationServiceImpl.mobileCertify request:" + LoggerMaskUtils.maskString(ToStringBuilder.reflectionToString(base)));
        /**
         * flag表示业务认证成功或者失败，success表示当前操作是否成功
         */
        Result result = new Result(false);
        /**
         * 如果认证开关关闭直接返回结果
         */
        if ("off".equals(bisConfig.get("BIS.AUTH.SWITCH"))) {
            logger.info("--该环境认证开关已关闭--");
            result.setSuccess(true);
            result.setModel("flag", true);
            result.setResultCode(ProcCodeConstants.PROC_CODE_200W1001);
            result.setErrorMsg("该环境认证开关已关闭");
            return result;
        }
        /**
         * 检验参数
         */
        if (!checkMobileCertRequest(base, result)) {
            return result;
        }
        try {
            String outStlmcd = "zcxzxMob";
            String beanName = outStlmcd + "ProviderClient";
            /*
             * 是否走直连验证实名认证,true每次都调用实名认证接口
             */
            if (!base.isDirectFlag()) {
            	/**央行检测 要求身份照掩码处理 ssj 2017-05-05*/
                logger.info(base.getCardHolder() + "," + LoggerMaskUtils.maskString(base.getIdentityCode()) + ",走有缓存接口调用认证！");
                /*
                 * 判断输入参数是否已经认证过，如果已经认证过，直接从数据库中获取历史信息返回，否则调用认证接口
                 */
                BisRealNameCertify mobileCertify = bisRealNameCertifyManager.getBisMobileCertify(base.getCardHolder(),
                        base.getIdentityCode(), base.getMobileNumber(), outStlmcd);
                if ((null == mobileCertify) || ((null != mobileCertify)
                        && TollyConstants.REALNAME_STATUS_NOMONEY.equals(mobileCertify.getState()))) {
                    MobileCertifyRemoteService mobileCertifyRemoteService = (MobileCertifyRemoteService) SpringContextUtil
                            .getBean(beanName);
                    result = mobileCertifyRemoteService.mobileCertify(base);

                    if (null != result.getModel("status")) {
                        /*
                         * 增加结果到数据库中
                         */
                        insertBisRealNameCertify(base, result, outStlmcd);
                    }
                } else {
                    // 根据数据库记录状态返回调用者
                    if (mobileCertify.getState().equals(TollyConstants.REALNAME_STATUS_CONSISTENT)) {
                        result.setSuccess(true);
                        result.setModel("flag", true);
                        logger.info("直接返回数据库记录，手机认证成功！");
                    } else if ((TollyConstants.REALNAME_STATUS_INCONSISTENT).equals(mobileCertify.getState())) {
                        result.setSuccess(true);
                        result.setModel("flag", false);
                        logger.info("直接返回数据库记录，手机认证失败！");
                    } else {
                        result.setSuccess(false);
                        result.setModel("flag", false);
                        logger.info("直接返回数据库记录，手机认证不存在！");
                    }
                }
            } else {
                logger.info(base.getCardHolder() + "," + base.getIdentityCode() + ",没有走缓存直接调用" + outStlmcd + "验证接口！");
                MobileCertifyRemoteService mobileCertifyRemoteService = (MobileCertifyRemoteService) SpringContextUtil
                        .getBean(beanName);
                result = mobileCertifyRemoteService.mobileCertify(base);

                if (null != result.getModel("status")) {
                    /*
                     * 增加结果到数据库中
                     */
                    insertBisRealNameCertify(base, result, outStlmcd);
                }
            }

            logger.error(
                    "BisCertificationServiceImpl.mobileCertify response:" + ToStringBuilder.reflectionToString(result));
        } catch (Exception e) {
            logger.error("BisCertificationServiceImpl.mobileCertify: ", e);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100F1002);
            result.setSuccess(false);
            result.setModel("flag", false);
        }
        return result;

    }

    @Override
    public Result fourElementsCertify(IdentityInfoMessage base) {
    	/**央行检测 要求身份照掩码处理 sj 2017-11-02*/
        logger.error(
                "BisCertificationServiceImpl.fourElementsCertify request:" + LoggerMaskUtils.maskString(ToStringBuilder.reflectionToString(base)));
        /**
         * flag表示业务认证成功或者失败，success表示当前操作是否成功
         */
        Result result = new Result(false);
        /**
         * 如果认证开关关闭直接返回结果
         */
        if ("off".equals(bisConfig.get("BIS.AUTH.SWITCH"))) {
            logger.info("--该环境认证开关已关闭--");
            result.setSuccess(true);
            result.setModel("flag", true);
            result.setResultCode(ProcCodeConstants.PROC_CODE_200W1001);
            result.setErrorMsg("该环境认证开关已关闭");
            return result;
        }
        /**
         * 检验参数
         */
        if (!checkFourElementsCertRequest(base, result)) {
            return result;
        }
        try {
            String outStlmcd = "zcxzxFES";
            String beanName = outStlmcd + "ProviderClient";
            /*
             * 是否走直连验证实名认证,true每次都调用实名认证接口
             */
            if (!base.isDirectFlag()) {

                logger.info(base.getCardHolder() + "," + base.getIdentityCode() + ",走有缓存接口调用认证！");
                /*
                 * 判断输入参数是否已经认证过，如果已经认证过，直接从数据库中获取历史信息返回，否则调用认证接口
                 */
                BisRealNameCertify fesCertify = bisRealNameCertifyManager.getBisBankCardCertify(base.getCardHolder(),
                        base.getIdentityCode(), base.getMobileNumber(), base.getBankCardNo(), outStlmcd);
                if ((null == fesCertify) || ((null != fesCertify)
                        && TollyConstants.REALNAME_STATUS_NOMONEY.equals(fesCertify.getState()))) {
                    FourElementsCertifyRemoteService mobileCertifyRemoteService = (FourElementsCertifyRemoteService) SpringContextUtil
                            .getBean(beanName);
                    result = mobileCertifyRemoteService.fourElementsCertify(base);

                    if (null != result.getModel("status")) {
                        /*
                         * 增加结果到数据库中
                         */
                        insertBisRealNameCertify(base, result, outStlmcd);
                    }
                } else {
                    // 根据数据库记录状态返回调用者
                    if (fesCertify.getState().equals(TollyConstants.REALNAME_STATUS_CONSISTENT)) {
                        result.setSuccess(true);
                        result.setModel("flag", true);
                        logger.info("直接返回数据库记录，四要素认证成功！");
                    } else if ((TollyConstants.REALNAME_STATUS_INCONSISTENT).equals(fesCertify.getState())) {
                        result.setSuccess(true);
                        result.setModel("flag", false);
                        logger.info("直接返回数据库记录，四要素认证失败！");
                    } else {
                        result.setSuccess(false);
                        result.setModel("flag", false);
                        logger.info("直接返回数据库记录，四要素认证不存在！");
                    }
                }
            } else {
                FourElementsCertifyRemoteService mobileCertifyRemoteService = (FourElementsCertifyRemoteService) SpringContextUtil
                        .getBean(beanName);
                result = mobileCertifyRemoteService.fourElementsCertify(base);

                if (null != result.getModel("status")) {
                    /*
                     * 增加结果到数据库中
                     */
                    insertBisRealNameCertify(base, result, outStlmcd);
                }
            }

            logger.error("BisCertificationServiceImpl.fourElementsCertify response:"
                    + ToStringBuilder.reflectionToString(result));
        } catch (Exception e) {
            logger.error("BisCertificationServiceImpl.fourElementsCertify: ", e);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100F1002);
            result.setSuccess(false);
            result.setModel("flag", false);
        }
        return result;

    }

    /**
     * 新增数据到数据库
     */
    private void insertBisQueryValidator(IdentityInfoMessage base, Result result) {
        try {
            EduInfo eduInfo = new EduInfo();
            eduInfo.setQueryDate(new Date());
            eduInfo.setName(base.getCardHolder());
            eduInfo.setStatus((String) result.getModel("status"));
            eduInfo.setResMsg((String) result.getErrorMsg());
            eduInfo.setResData((String) result.getModel("resData"));
            eduInfo.setCreatedTs(new Date());
            eduInfo.setIdentityCode(base.getIdentityCode());
            bisQueryValidatorManager.insertEduInfo(eduInfo);
        } catch (Exception e) {
            logger.error("insertBisQueryValidator is error!", e.getMessage());
        }
    }

    @Override
    public Result queryCertification(ExPayBaseMessage base) {

        // 日志输出隐藏信用卡cvv2
        ExPayBaseMessage logData = getPrintMsg(base);
        /**央行检测 要求身份照掩码处理 sj 2017-11-02*/
        logger.error("BisCertificationServiceImpl.queryCertification request："
                + logData.toString());
        Result result = new Result();
        try {
            // 发起银行查询之前先查询鉴权流水表数据
            BisBankContractSerialInfo queryRes = getContractInfoBySerialNum(base);
            if (null != queryRes && BankContractConstants.CONTRACT_SUCCESS.equals(queryRes.getContractState())) {
                // 鉴权成功
                result.setSuccess(true);
                if (BisBankInterfaceChannel._11.value.equals(base.getBankIntrChann().value)) {
                    CmbcExPayMessage resMsg = new CmbcExPayMessage();
                    resMsg.setFlag(true);
                    resMsg.setRetType(CmbcConstants.RESP_TYPE_SUCCESS);
                    resMsg.setRetCode(CmbcConstants.EXEC_CODE_SUCCESS);
                    resMsg.setOriRetType(CmbcConstants.RESP_TYPE_SUCCESS);
                    resMsg.setOriRetCode(CmbcConstants.EXEC_CODE_SUCCESS);
                    resMsg.setValidStatus(CmbcConstants.VALIDATE_STATUS_SUCCESS);
                    result.setDefaultModel(resMsg);
                }
                logger.error(
                        "BisCertificationServiceImpl.certification res：" + ToStringBuilder.reflectionToString(result));
                return result;
            }

            String outStlmCd = BankConstants.BANK_LOGO_CMBCADPAY; // 默认走民生通道
            base.setOutStlmCd(outStlmCd);
            // 获取SPRING加载的快捷BeanName
            String beanName = outStlmCd + "-" + "EXPAY";

            ExPayInteractRemoteService exPayService = (ExPayInteractRemoteService) SpringContextUtil.getBean(beanName);
            // 鉴权查询请求
            result = exPayService.queryOrder(base);
            logger.error("BisCertificationServiceImpl.certification res：" + ToStringBuilder.reflectionToString(result));
        } catch (Exception e) {
            logger.error("BisCertificationServiceImpl.certification: ", e);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100F1002);
            result.setSuccess(false);
        }
        return result;
    }

    /**
     * 根据请求银行流水号获取签约流水数据
     * 
     * @param message
     * @return
     */
    public BisBankContractSerialInfo getContractInfoBySerialNum(ExPayBaseMessage message) {
        BisBankContractSerialInfo bisBankContractSerialInfo = new BisBankContractSerialInfo();
        bisBankContractSerialInfo.setBankCode(message.getBank());
        bisBankContractSerialInfo.setBankBizProdCode(message.getBankBusProd().value);
        bisBankContractSerialInfo.setIntrfaceChannelCode(message.getBankIntrChann().value);
        bisBankContractSerialInfo.setSerialNumber(message.getBankOrderId());
        bisBankContractSerialInfo = bankContractSerialInfoDAO.getContractInfobySerialNum(bisBankContractSerialInfo);
        return bisBankContractSerialInfo;
    }

}
